﻿/****************************************************************************
**
* @Project : Frameworks
* @File: aggregate.h
* @Description:
* @Copyright: Copyright (c) 2014
* @Company:
* @WebSite: http://www.zchx.com/
* @author:
* @Revision History
* <pre>
* ----------------------------------------------------------------------
*   Ver     Date       Who        Comments
* ----- ----------  --------  ------------------------------------------
*   1.0  2013/08/12    yeguoxiong      FOR QT 5.1.0
* ----------------------------------------------------------------------
**
****************************************************************************/

#ifndef PLUGINSPEC_H
#define PLUGINSPEC_H

#include "extensionsystem_global.h"

#include <QString>
#include <QList>
#include <QHash>

QT_BEGIN_NAMESPACE
class QStringList;
QT_END_NAMESPACE

namespace ExtensionSystem {

namespace Internal {
class PluginSpecPrivate;
class PluginManagerPrivate;
} // namespace Internal

class IPlugin;

/**
 * @struct PluginDependency
 * @brief 插件依赖关系结构体
 * @details 描述一个插件对其他插件的依赖信息，包括依赖类型（必需或可选）
 */
struct EXTENSIONSYSTEM_EXPORT PluginDependency
{
    /**
     * @enum Type
     * @brief 依赖类型枚举
     */
    enum Type {
        Required,    ///< 必需依赖，没有该插件则当前插件无法加载
        Optional     ///< 可选依赖，没有该插件当前插件仍可加载，但可能功能受限
    };

    /**
     * @brief 构造函数
     * @details 初始化依赖类型为Required
     */
    PluginDependency() : type(Required) {}

    QString name;     ///< 依赖插件的名称
    QString version;  ///< 依赖插件的版本
    Type type;        ///< 依赖类型

    /**
     * @brief 相等运算符
     * @param other 另一个PluginDependency对象
     * @return 两个对象是否相等
     */
    bool operator==(const PluginDependency &other) const;
};

/**
 * @brief 计算PluginDependency的哈希值
 * @param value PluginDependency对象
 * @return 哈希值
 */
uint qHash(const ExtensionSystem::PluginDependency &value);

/**
 * @struct PluginArgumentDescription
 * @brief 插件参数描述结构体
 * @details 描述插件支持的命令行参数信息
 */
struct EXTENSIONSYSTEM_EXPORT PluginArgumentDescription
{
    QString name;        ///< 参数名称
    QString parameter;   ///< 参数格式
    QString description; ///< 参数描述
};

/**
 * @class PluginSpec
 * @brief 插件规范类
 * @details 包含插件的元数据信息、依赖关系和运行状态
 *          是插件系统中描述和管理插件的核心数据结构
 *          // TODO: Qt5.15.2升级 - 考虑使用Q_ENUM_NS宏注册State枚举
 */
class EXTENSIONSYSTEM_EXPORT PluginSpec
{
public:
    /**
     * @enum State
     * @brief 插件状态枚举
     * @details 描述插件在生命周期中的不同状态
     */
    enum State {
        Invalid,       ///< 无效状态，插件信息无法读取
        Read,          ///< 已读取状态，插件元数据已加载
        Resolved,      ///< 已解析状态，依赖关系已解决
        Loaded,        ///< 已加载状态，插件库已加载
        Initialized,   ///< 已初始化状态，插件已初始化
        Running,       ///< 运行状态，插件正常运行中
        Stopped,       ///< 已停止状态，插件已停止
        Deleted        ///< 已删除状态，插件已卸载并释放
    };

    /**
     * @brief 析构函数
     * @details 清理插件规范资源
     */
    ~PluginSpec();

    // information from the xml file, valid after 'Read' state is reached
    /**
     * @brief 获取插件名称
     * @return 插件名称
     */
    QString name() const;

    /**
     * @brief 获取插件版本
     * @return 插件版本字符串
     */
    QString version() const;

    /**
     * @brief 获取兼容版本
     * @return 兼容版本字符串
     */
    QString compatVersion() const;

    /**
     * @brief 获取供应商信息
     * @return 供应商名称
     */
    QString vendor() const;

    /**
     * @brief 获取版权信息
     * @return 版权字符串
     */
    QString copyright() const;

    /**
     * @brief 获取许可证信息
     * @return 许可证字符串
     */
    QString license() const;

    /**
     * @brief 获取插件描述
     * @return 插件描述字符串
     */
    QString description() const;

    /**
     * @brief 获取插件URL
     * @return 插件相关URL
     */
    QString url() const;

    /**
     * @brief 获取插件分类
     * @return 插件分类字符串
     */
    QString category() const;

    /**
     * @brief 检查是否为实验性插件
     * @return 是实验性插件返回true，否则返回false
     */
    bool isExperimental() const;

    /**
     * @brief 检查是否默认禁用
     * @return 默认禁用返回true，否则返回false
     */
    bool isDisabledByDefault() const;

    /**
     * @brief 检查是否启用
     * @return 启用返回true，否则返回false
     */
    bool isEnabled() const;

    /**
     * @brief 检查是否间接禁用
     * @return 间接禁用返回true，否则返回false
     */
    bool isDisabledIndirectly() const;

    /**
     * @brief 获取依赖列表
     * @return PluginDependency对象列表
     */
    QList<PluginDependency> dependencies() const;

    typedef QList<PluginArgumentDescription> PluginArgumentDescriptions;
    /**
     * @brief 获取参数描述列表
     * @return PluginArgumentDescription对象列表
     */
    PluginArgumentDescriptions argumentDescriptions() const;

    // other information, valid after 'Read' state is reached
    /**
     * @brief 获取插件位置
     * @return 插件位置字符串
     */
    QString location() const;

    /**
     * @brief 获取插件文件路径
     * @return 插件文件的绝对路径
     */
    QString filePath() const;

    /**
     * @brief 设置插件启用状态
     * @param value 启用状态
     */
    void setEnabled(bool value);

    /**
     * @brief 设置默认禁用状态
     * @param value 默认禁用状态
     */
    void setDisabledByDefault(bool value);

    /**
     * @brief 设置间接禁用状态
     * @param value 间接禁用状态
     */
    void setDisabledIndirectly(bool value);

    /**
     * @brief 获取插件参数
     * @return 参数字符串列表
     */
    QStringList arguments() const;

    /**
     * @brief 设置插件参数
     * @param arguments 参数字符串列表
     */
    void setArguments(const QStringList &arguments);

    /**
     * @brief 添加插件参数
     * @param argument 要添加的参数
     */
    void addArgument(const QString &argument);

    /**
     * @brief 检查是否提供指定插件功能
     * @param pluginName 插件名称
     * @param version 版本字符串
     * @return 提供指定功能返回true，否则返回false
     */
    bool provides(const QString &pluginName, const QString &version) const;

    // dependency specs, valid after 'Resolved' state is reached
    /**
     * @brief 获取依赖规范映射
     * @return 依赖关系到PluginSpec的映射
     */
    QHash<PluginDependency, PluginSpec *> dependencySpecs() const;

    // linked plugin instance, valid after 'Loaded' state is reached
    /**
     * @brief 获取插件实例
     * @return IPlugin接口指针
     */
    IPlugin *plugin() const;

    // state
    /**
     * @brief 获取插件状态
     * @return 当前插件状态
     */
    State state() const;

    /**
     * @brief 检查是否有错误
     * @return 有错误返回true，否则返回false
     */
    bool hasError() const;

    /**
     * @brief 获取错误字符串
     * @return 错误描述字符串
     */
    QString errorString() const;

private:
    /**
     * @brief 构造函数
     * @details 私有构造函数，只能由PluginManager创建
     */
    PluginSpec();

    Internal::PluginSpecPrivate *d; ///< 私有实现指针
    friend class Internal::PluginManagerPrivate;
    friend class Internal::PluginSpecPrivate;
};

} // namespace ExtensionSystem

#endif // PLUGINSPEC_H

